#include "../include/hero.h"
#include "../include/play.h"

#define Maximum(a, b) ((a > b) ? a : b)
#define Minimum(a, b) ((a < b) ? a : b)

Hero::Hero()
{
    setSpriteImage("img/sprite.png");

    spriteX=3;
    spriteY=3;
    spriteW=sprites->w/spriteX;
    spriteH=sprites->h/spriteY;

    frame=0;
    sure = 0.02;
    frameCount = spriteX*spriteY;
    frameCounter=1;
    thisTime = 0.0;
    lastTime = 0.0;

    setX(400);
    setY(500);
    bounce.w=spriteW;
    bounce.h=spriteH;

    frameBounce.x = 0;
    frameBounce.y = 0;
    frameBounce.w = spriteW;
    frameBounce.h = spriteH;

    deltaJump = -128;
    direction = RIGHT;
    setWalkState(false);
    setJumpState(false);
    setDeltaSure();

}

Hero::~Hero()
{

}

void Hero::Render(SDL_Surface* screen)
{
    SDL_Rect spriteBounce = getBounce2();
    SDL_Rect spriteFrameBounce = getFrameBounce();

    SDL_BlitSurface(sprites,&spriteFrameBounce,screen,&spriteBounce);
}

void Hero::Logic()
{
	if (getWalkState() || getJumpState())
	{
        setDeltaSure();
	    sure -= deltaSure;
	    frame = direction;
        if (sure<0)
        {
            SDL_Rect spriteBounce = getBounce();
            switch(direction)
            {
                case LEFT:
                {
                    if(!jumpState)
                    {
                        setSpriteFrame();
                        spriteBounce.x-=2;
                        if(frameCounter>spriteX-1)
                        {
                            //Adımını bitirdikten sonra iki ayağını aynı hizaya getiriyorum
                            frameCounter=0;
                            setSpriteFrame();
                            //////////////////////////////////////////

                            //Yürüme işi tamamiyle bitti
                            setWalkState(false);
                            frame=direction;
                            direction = NONE;
                        }
                        else
                        {
                            frame++;
                            frameCounter++;
                        }
                    }
                    else
                    {
                        spriteBounce.x-=12;
                    }
                    setBounce(spriteBounce);

                    if(CheckCollision(this,tugla))
                    {
                        spriteBounce.x+=2;
                        setBounce(spriteBounce);
                    }

                    sure = 0.02;
                    break;
                }
                case RIGHT:
                {
                    if(!jumpState)
                    {
                        setSpriteFrame();
                        spriteBounce.x+=2;
                        if(frameCounter>spriteX-1)
                        {
                            //Adımını bitirdikten sonra iki ayağını aynı hizaya getiriyorum
                            frameCounter=0;
                            setSpriteFrame();
                            //////////////////////////////////////////

                            //Yürüme işi tamamiyle bitti
                            setWalkState(false);
                            frame=direction;
                            direction = NONE;
                        }
                        else
                        {
                            frame++;
                            frameCounter++;
                        }
                    }
                    else
                    {
                        spriteBounce.x+=12;
                    }
                    setBounce(spriteBounce);

                    if(CheckCollision(this,tugla))
                    {
                        spriteBounce.x-=2;
                        setBounce(spriteBounce);
                    }
                    sure = 0.02;

                    break;
                }

                case JUMP:
                {
                    jumpState = true;
                }
            }

            // ZIPLAAAAAAAAAAAAAAAAAAA
            if(jumpState)
            {
                //Yukarı
                if (deltaJump<0)
                    deltaJump /=2;

                //Aşşa
                if (deltaJump>0)
                    deltaJump *=2;

                if(deltaJump == 0)
                    deltaJump = 1;


                if(CheckCollision(this,tugla))
                {
                    deltaJump*=-1;
                }

                spriteBounce.y+=deltaJump;
                setBounce(spriteBounce);

                if(deltaJump>128)
                {
                    setWalkState(false);
                    deltaJump = -128;
                    jumpState = false;
                }


                sure = 0.05;
            }
            /////////////////////////////////////////////////

        }
	}
}

bool Hero::CheckCollision(Temel* entityA, Temel* entityB)
{
    SDL_Rect boundsA = entityA->getBounce2();
    SDL_Rect boundsB = entityB->getBounce2();

    int x1 = Maximum(boundsA.x, boundsB.x);
	int y1 = Maximum(boundsA.y, boundsB.y);
	int x2 = Minimum(boundsA.x + boundsA.w, boundsB.x + boundsB.w);
	int y2 = Minimum(boundsA.y + boundsA.h, boundsB.y + boundsB.w);

	int width = x2 - x1;
	int height = y2 - y1;

	if(width > 0 && height > 0)
	{
		SDL_Rect collisionRect = {x1, y1, width, height};

		SDL_Rect normalA = entityA->NormalizeBounds(collisionRect);
        SDL_Rect normalB = entityB->NormalizeBounds(collisionRect);

        for(int y = 0; y <= collisionRect.h; y++)
            for(int x = 0; x <= collisionRect.w; x++)
                if(GetAlphaXY(entityA, normalA.x + x, normalA.y + y) && GetAlphaXY(entityB, normalB.x + x, normalB.y + y))
                    return true;

	}

	return false;
}

void Hero::sendTugla(Tugla* _tugla)
{
    tugla = _tugla;
}

void Hero::setDeltaSure()
{
    lastTime = thisTime;
    thisTime = SDL_GetTicks();
    deltaSure = (thisTime - lastTime) / 1000.0;
}

void Hero::setSpriteFrame()
{
    frameBounce.x = frameCounter*spriteW;
    frameBounce.y = frame*spriteH;
    frameBounce.w = spriteW;
	frameBounce.h = spriteH;
}

void Hero::jump()
{

}

bool Hero::GetAlphaXY(Temel* entity, int x, int y)
{
	int bpp = entity->getSurface()->format->BytesPerPixel;
	Uint8* p = (Uint8*)entity->getSurface()->pixels + y * entity->getSurface()->pitch + x * bpp;
	Uint32 pixelColor;

	switch(bpp)
	{
		case(1):
			pixelColor = *p;
			break;
		case(2):
			pixelColor = *(Uint16*)p;
			break;
		case(3):
			if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
				pixelColor = p[0] << 16 | p[1] << 8 | p[2];
			else
				pixelColor = p[0] | p[1] << 8 | p[2] << 16;
			break;
		case(4):
			pixelColor = *(Uint32*)p;
			break;
	}

	Uint8 red, green, blue, alpha;
	SDL_GetRGBA(pixelColor, entity->getSurface()->format, &red, &green, &blue, &alpha);

	return alpha > 200;
}
